import {
  Controller,
  Get,
  Inject,
  Req,
  Res,
  Headers,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import express from 'express';

@Controller('jwt')
export class JwtController {
  @Inject(JwtService)
  private jwtService: JwtService;

  /**
   * 生成 jwt token
   * passthrough: true 表示将return xx 的值返回给前端。
   * 一般情况下，若声明了@Res(),需要使用response.send(‘xx’) 来返回值
   * 为了防止两个返回值互相冲突，若要返回return 中的值，需配置{ passthrough: true }
   * @param response
   * @returns
   */
  @Get('generate-jwt-token')
  generate_jwt_token(@Res({ passthrough: true }) response: express.Response) {
    const newToken = this.jwtService.sign({
      age: 23,
      name: 'John Doe',
    });
    console.log('----token---', newToken);
    response.setHeader('token', newToken);
    return 'hello';
  }

  /**
   * 解码 jwt token
   * @param request
   * @returns
   */
  @Get('decode-jwt-token')
  decode_jwt_token(@Req() request: express.Request) {
    const token = request.header('token');
    if (!token) {
      throw new Error('token is required');
    }
    // this.jwtService.decode: 只解码 token，不能验证 token 是否有效
    // this.jwtService.verify: 验证 token 是否有效，并返回解码后的内容
    const decodedToken = this.jwtService.verify(token);
    console.log('----token---', decodedToken);
    return decodedToken;
  }

  @Get('token-validation')
  ttt(
    @Headers('token') token: string,
    @Req() request: express.Request,
    @Res({ passthrough: true }) response: express.Response,
  ) {
    if (token) {
      console.log('----token---', token);
      try {
        const data = this.jwtService.verify(token);
        console.log('----data---', data);
        // update token with new age
        const newToken = this.jwtService.sign({
          age: data.age + 1,
        });
        response.setHeader('token', newToken);
        return newToken;
      } catch (e) {
        console.log(e);
        throw new UnauthorizedException();
      }
    } else {
      throw new UnauthorizedException();
    }
  }
}
